/* -----------------
* brief
* 1. this is code gen by tools
 */

package service

import (
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/mjiulee/lego"
	"saas_sys_base/common"
	. "saas_sys_base/modules/user/models"
	"saas_sys_base/sysconfig"
	"strings"
	"time"
)

type AppTenantUserRelService struct {
	// add your model here
	tbAppTenantUserRel AppTenantUserRel
}

func (t *AppTenantUserRelService) ListAppTenantUserRel(keyword string, page, psize int) ([]map[string]string, int64, error) {
	// 业务查询
	queryMap := map[string]interface{}{
		"table":  map[string]string{"table": "tb_app_tenant_user_rel", "alias": "t1"},
		"fields": []string{"t1.*"},
		"join":   []map[string]string{
			// map[string]string{"table": "tb_xx as t2", "on": "t2.xid = t1.id"},
		},
		"where": []lego.QMapWhereField{
			//{"t1.if_del", "=", 0, "AND", false},
		},
		"search": map[string]string{
			//"t1.id": req.Keyword,
		},
		"orders": []string{"t1.id asc"},
		"page": map[string]int{
			"page":  page,
			"psize": psize,
		},
	}
	return lego.QueryListByMap(queryMap)
}

/* 根据id获取记录
 * -----------------
 */
func (t *AppTenantUserRelService) GetAppTenantUserRelById(id int64) *AppTenantUserRel {
	return t.tbAppTenantUserRel.RecodeById(id)
}

func (t *AppTenantUserRelService) GetAppTenantUserRelByWho(who common.Who /*MiniAppId int64, tid int64, sysUid int64*/) *AppTenantUserRel {
	return t.tbAppTenantUserRel.RecodeByWho(who)
}

/* 添加
 * -----------------
 */
func (t *AppTenantUserRelService) SaveAppTenantUserRel(item2add *AppTenantUserRel) bool {
	return t.tbAppTenantUserRel.AddRecode(item2add)
}

/* 删除(硬删除)*/
func (t *AppTenantUserRelService) DelAppTenantUserRelById(id int64) bool {
	return t.tbAppTenantUserRel.DelRecodeById(id)
}

/* 更新
 * -----------------*/
func (t *AppTenantUserRelService) UpdateAppTenantUserRel(rc *AppTenantUserRel) bool {
	return t.tbAppTenantUserRel.UpdateRecode(rc)
}

//以下是自定义函数

//TODO 这个函数暂时这样粗暴的提供一个对外接口，仅给管理端用，以后想其它接口封装替代之
func (t *AppTenantUserRelService) UserLogin(who *common.Who /*MiniAppId int64, tid int64, sysUid int64*/) (relUser *AppTenantUserRel, tokenString string, err error) {
	if who.Uid != 0 {
		return nil, "", errors.New("only support sys admin")
	}
	return t.userLogin(*who)
}

func (t *AppTenantUserRelService) userLogin(who common.Who /*MiniAppId int64, tid int64, sysUid int64*/) (relUser *AppTenantUserRel, tokenString string, err error) {

	//t.appmanagerService.HasPermissionInTenant()
	/* TODO 减少对appmanager的耦合 hasPermission, err := t.appmanagerService.CheckAppTenantPermission(who)
	if !hasPermission {
		return nil, "", err //app未开通不能登录
	}*/
	rel := t.tbAppTenantUserRel.RecodeByWho(who /*MiniAppId, tid, sysUid*/)
	if rel == nil {
		item2add := new(AppTenantUserRel)
		item2add.MiniAppId = who.GetMiniAppId()
		item2add.TenantId = who.GetTenantId()
		item2add.Uid = who.GetUid()
		if false == t.tbAppTenantUserRel.AddRecode(item2add) {
			return nil, "", errors.New("UserLogin Failed in AppTenantUserRelService UserLogin")
		}
		rel = item2add
	}

	/*PosId := PosId{
		MiniAppId:MiniAppId,
		Tid:tid,
		SysUid:sysUid,
	}*/
	RelId := rel.Id
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, UserRelCustomClaims{
		RelId,
		jwt.StandardClaims{ExpiresAt: time.Now().Add(TOKEN_EXPIRE_DURATION).Unix()},
	})

	/*token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"rel_id": rel.Id,
		"exp": time.Now().Add(time.Hour * 24).Unix(),
		//"exp": time.Now().Add(time.Minute * 3).Unix(),
	})*/

	tokenString, err = token.SignedString([]byte(sysconfig.SecretKey()))
	if err != nil {
		return nil, "", errors.New("token生成失败")
	}

	return rel, tokenString, nil
}

func (t *AppTenantUserRelService) CheckUserToken(passToken string, timestamp string) (UserRel *AppTenantUserRel, err error) {
	if len(passToken) <= 0 || len(timestamp) <= 0 {
		return nil, errors.New("token/timestamp参数不能为空")
	}

	/*token, err := jwt.Parse(passToken, func(token *jwt.Token) (interface{}, error) {
		return []byte(config.SecretKey()), nil
	})*/

	token, err := jwt.ParseWithClaims(passToken, &UserRelCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(sysconfig.SecretKey()), nil
	})

	if err != nil || token == nil {
		if strings.HasPrefix(err.Error(), "token is expired") {
			return nil, err
		}
		return nil, errors.New("token验证失败")
	}
	claims, ok := token.Claims.(*UserRelCustomClaims)
	if !ok || !token.Valid {
		return nil, errors.New("token验证失败")
	}

	UserRel = t.GetAppTenantUserRelById(claims.RelId)
	if UserRel == nil {
		return nil, fmt.Errorf("找不到用户, RelId<%d>", claims.RelId)
	}
	return UserRel, nil
}
